package com.qk.management.config;

import com.qk.common.enums.ClueEnum;
import com.qk.common.enums.ClueEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.service.DefaultStateMachineService;
import org.springframework.statemachine.service.StateMachineService;
import org.springframework.statemachine.transition.Transition;

import java.util.EnumSet;

/**
 * @Author:gzc
 * @Date: 2025/10/16 9:56
 * @Description:
 */
@Configuration
@EnableStateMachineFactory(name = "clueStateMachineFactory") // 用Factory模式，支持多实例（每个线索一个状态机）
@Slf4j
public class ClueStateMachineConfig extends StateMachineConfigurerAdapter<ClueEnum, ClueEvent> {
    // 1. 配置状态（初始状态、所有可能的状态）
    @Override
    public void configure(StateMachineStateConfigurer<ClueEnum, ClueEvent> states) throws Exception {
        states
                .withStates()
                .initial(ClueEnum.WAIT_ALLOCATION) // 初始状态：待分配（对应线索创建时的状态）
                .states(EnumSet.allOf(ClueEnum.class)); // 所有状态
    }

    // 2. 配置状态流转规则（核心：状态→事件→目标状态）
    @Override
    public void configure(StateMachineTransitionConfigurer<ClueEnum, ClueEvent> transitions) throws Exception {
        transitions
                // 规则1：待分配 + 分配事件 → 待跟进
                .withExternal()
                .source(ClueEnum.WAIT_ALLOCATION).target(ClueEnum.WAIT_TRACK)
                .event(ClueEvent.ASSIGN)
                .and()
                // 规则2：待跟进 + 开始跟进事件 → 跟进中
                .withExternal()
                .source(ClueEnum.WAIT_TRACK).target(ClueEnum.TRACKING)
                .event(ClueEvent.START_TRACK)
                .and()
                // 规则3：待跟进 + 标记伪线索事件 → 伪线索
                .withExternal()
                .source(ClueEnum.WAIT_TRACK).target(ClueEnum.FALSE_CLUE)
                .event(ClueEvent.MARK_FALSE)
                .and()
                // 规则4：待跟进 + 转商机事件 → 转商机
                .withExternal()
                .source(ClueEnum.WAIT_TRACK).target(ClueEnum.CONVERT_TO_BUSINESS)
                .event(ClueEvent.CONVERT_TO_BIZ)
                .and()
                // 规则5：跟进中 + 标记伪线索事件 → 伪线索
                .withExternal()
                .source(ClueEnum.TRACKING).target(ClueEnum.FALSE_CLUE)
                .event(ClueEvent.MARK_FALSE)
                .and()
                // 规则5：跟进中 + 转商机事件 → 转商机
                .withExternal()
                .source(ClueEnum.TRACKING).target(ClueEnum.CONVERT_TO_BUSINESS)
                .event(ClueEvent.CONVERT_TO_BIZ);
    }

    // 3. 配置状态机监听器（监听状态变更，执行额外业务逻辑）
    @Override
    public void configure(StateMachineConfigurationConfigurer<ClueEnum, ClueEvent> config) throws Exception {
        config
                .withConfiguration()
                .autoStartup(true)
                .listener(new StateMachineListenerAdapter<ClueEnum, ClueEvent>() {
                    // 状态流转成功后触发
                    @Override
                    public void transition(Transition<ClueEnum, ClueEvent> transition) {
                        if (transition.getSource() != null && transition.getTarget().getId() != null) {
                            ClueEnum from = transition.getSource().getId();
                            ClueEnum to = transition.getTarget().getId();
                            log.info("线索状态变更：{} → {}", from, to);
                        }
                    }
                });
    }

    @Bean("clueStateMachineService")
    public StateMachineService<ClueEnum, ClueEvent> stateMachineService(
            StateMachineFactory<ClueEnum, ClueEvent> clueStateMachineFactory) {
        // DefaultStateMachineService 是 StateMachineService 的默认实现，需传入 StateMachineFactory
        return new DefaultStateMachineService<>(clueStateMachineFactory);
    }

}
